#ifndef CAMERA_H
#define CAMERA_H

#include <math.h>
#include <QDebug>

#ifndef CROSSPROD
#define CROSSPROD(p1,p2,p3) \
   p3.x = p1.y*p2.z - p1.z*p2.y; \
   p3.y = p1.z*p2.x - p1.x*p2.z; \
   p3.z = p1.x*p2.y - p1.y*p2.x
#endif

#define DTOR            0.0174532925

/* Define a stereo camera to be used in the bench system */

namespace camera
{
typedef struct XYZ
{
    double x, y, z;
} XYZ;


typedef struct Camera
{
    XYZ vp;              /* View position           */
    XYZ vd;              /* View direction vector   */
    XYZ vu;              /* View up direction       */

    double fnear;
    double ffar;

    double focallength;  /* Focal Length along vd   */
    double aperture;     /* Camera aperture         */
    double eyesep;       /* Eye separation          */

    int screenwidth, screenheight;
} Camera;

class Utility
{
public:
    static void Normalise(XYZ *p)
    {
       double length;

       length = sqrt(p->x * p->x + p->y * p->y + p->z * p->z);
       if (length != 0) {
          p->x /= length;
          p->y /= length;
          p->z /= length;
       } else {
          p->x = 0;
          p->y = 0;
          p->z = 0;
       }
    }

    static XYZ Direction( XYZ * p1, XYZ * p2 )
    {
        XYZ res;
        res.x = p2->x - p1->x;
        res.y = p2->y - p1->y;
        res.z = p2->z - p1->z;

        Normalise( & res );
        return res;
    }

    static void PrintCamera( Camera * camera )
    {
        qDebug() << "- Camera properties -";
        qDebug() << "  Aperture: " << camera->aperture;
        qDebug() << "  Eye sepration: " << camera->eyesep;
        qDebug() << "  Eye position: (" << camera->vp.x << "," << camera->vp.y << "," << camera->vp.z << ")";
        qDebug() << "  Direction: (" << camera->vd.x << "," << camera->vd.y << "," << camera->vd.z << ")";
        qDebug() << "  Up Vector: (" << camera->vu.x << "," << camera->vu.y << "," << camera->vu.z << ")";
    }


    static void RotateY( Camera * camera, double degree )
    {
        double s = sin( degree ), c = cos( degree );
        double x = camera->vp.x, z = camera->vp.z;
        camera->vp.x = c * x + s * z;
        camera->vp.z = - s * x + c * z;
    }
};

}
#endif // CAMERA_H
